# coding:utf-8
import os

from common.im_util import im_client, IM_LIST_REDIS_KEY
from common.schedule.opc_celery import celery_app
from common.utils import DB, redis_client
from common.models import model_factory

CURRENT_IM_USER_ID = 'current_im_user_id'


@celery_app.task(name='generate_im_token')
def generate_im_token(count=1000):
    """
    created by chenhj at 2017/8/22
    预生成1000个im_token做备用
    """
    host = os.environ.get('opc_host') or 'http://opc.88ba.com'
    if host == 'http://opc.88ba.com':
        return

    select_max_user_id_sql = """
        select max(id) from user
    """

    with DB() as session:
        res = session.execute(select_max_user_id_sql).fetchone()
        max_id = res[0]
        # 为没有im的用户生成im
        apply_im_token_for_user(session)

        # 用户表max_id以前的数据清除
        redis_client.zremrangebyscore(IM_LIST_REDIS_KEY, 0, max_id)

        cache_im_count = redis_client.zcard(IM_LIST_REDIS_KEY)

        cache_data = redis_client.zrange(
            IM_LIST_REDIS_KEY, 0, -1, desc=True, withscores=True
        )

        new_id = next_id = int(max_id + 1 if not cache_data else cache_data[0][1] + 1)

        pipeline = redis_client.pipeline()
        # 补全1000个
        while cache_im_count < count:
            print(next_id)
            new_id = next_id
            im_token = gen_token(new_id)
            next_id += 1          # 下一个用户的id
            if not im_token:
                continue
            cache_im_count += 1  # redis存储im的集合长度
            pipeline.zadd(IM_LIST_REDIS_KEY, new_id, im_token)

        # 写入缓存中生成im的最大用户id，用于为没有im的用户补上im
        pipeline.set(CURRENT_IM_USER_ID, new_id)
        pipeline.execute()


def apply_im_token_for_user(session):
    """
    create by ld_wu 2018-06-04
    查询没有im的用户，并为他们生成im
    :return:
    """
    try:
        current_im_user_id = redis_client.get(CURRENT_IM_USER_ID)
        query = session.query(model_factory.user.id).filter(
            model_factory.user.im_token == ''
        )
        if current_im_user_id:
            query = query.filter(model_factory.user.id > int(current_im_user_id))

        for each in query.all():
            im_token = gen_token(each.id)
            if im_token:
                session.execute(
                    '''update
                           user
                       set
                           im_token=:im_token
                       where
                           id=:id
                    ''',
                    dict(
                        im_token=im_token,
                        user_id=each.id
                    )
                )
        session.commit()
    except Exception as e:
        print('apply_im_token_for_user: {}'.format(repr(e)))


def gen_token(user_id):
    """
    create by ld_wu 2018-06-04
    生成im token
    :param user_id:
    :return:
    """
    im_token = ''
    try:
        im_token = im_client.apply_im_token(user_id)
    except:
        try:
            im_token = im_client.refresh_im_token(user_id)
        except Exception as e:
            print('gen_token: {}'.format(repr(e)))
    return im_token
